package org.hardcode.rpc.common.scanner.reference;

import org.hardcode.rpc.annotation.RpcReference;
import org.hardcode.rpc.common.scanner.ClassScanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import static java.lang.Class.forName;

/**
 * 在程序启动时，需要扫描类上标注的@RpcService注解,通过解析@RpcService注解的属性
 * 将服务提供者的元数据信息注册到注册中心，并且会将@RpcService 注解标注的实现类放入一个Map缓存中
 */
public class RpcReferenceScanner extends ClassScanner {

    private static final Logger LOGGER = LoggerFactory.getLogger(RpcReferenceScanner.class);

    /**
     * 扫描指定包下的类，并筛序使用@RpcService注解标注的类
     *
     * @desc 传入扫描的包名, 首先 会调用  通用类扫描器 ClassScanner中的getClassNameList() 方法
     * 获取指定包的所有类信息。接下来，会便利的
     */
    public static Map<String, Object> doScannerWithRpcServiceAnnotationFilterAndRegistryService(String scanPackage) throws IOException {

        //扫描指定包下的类
        Map<String, Object> handlerMap = new HashMap<>();
        //查询出的所有的额类名称
        List<String> classNameList = ClassScanner.getClassNameList(scanPackage, true);

        if (classNameList == null || classNameList.isEmpty()) {
            return handlerMap;
        }
        classNameList.stream().forEach((className) -> {
            try {
                Class<?> aClass = forName(className);
                //获取这个类的所有的字段
                Field[] declaredFields = aClass.getDeclaredFields();

                Stream.of(declaredFields).forEach((field -> {
                    RpcReference rpcReference = field.getAnnotation(RpcReference.class);
                    if (rpcReference != null) {
//TODO 处理后续逻辑，将@RpcReference注解标注的接口引用代理对象，放入全局缓存中
                        LOGGER.info("当前标注了@RpcReference注解的字段名称===>>> " + field.getName());
                        LOGGER.info("@RpcReference注解上标注的属性信息如下：");
                        LOGGER.info("version===>>> " + rpcReference.version());
                        LOGGER.info("group===>>> " + rpcReference.group());
                        LOGGER.info("registryType===>>> " + rpcReference.registryType());
                        LOGGER.info("registryAddress===>>> " + rpcReference.registryAddress());



                    }
                }));
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        });

        return handlerMap;

    }



}
